package com.just.boot.web.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.just.boot.web.bean.Manager;
import com.just.boot.web.mapper.ManagerMapper;
import com.just.boot.web.service.ManagerService;
import com.just.boot.utils.BusinessException;
import com.just.boot.utils.ConstUtil;
import com.just.boot.utils.enums.DataStatusEnum;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Properties;
import java.util.Random;

/**
 * @author Just
 */
@Service
@Transactional(rollbackFor=BusinessException.class)
public class ManagerServiceImpl  extends ServiceImpl<ManagerMapper, Manager> implements ManagerService {
    @Resource
    private ManagerMapper managerMapper;

    @Resource
    private HttpServletRequest request;

    @Resource
    private MailProperties mailProperties;

    @Override
    public Manager findByName(String username)throws BusinessException  {
        //通过用户名查询
        QueryWrapper<Manager> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Manager::getUsername,username)
                .eq(Manager::getStatus,ConstUtil.DEFAULT_STATE);
        return  managerMapper.selectOne(queryWrapper);
    }

    @Override
    public Manager saveManager(Manager manager,Integer checkCode) throws BusinessException {
        try {
            if (manager.getId()==null){
                manager.setCreateTime(DateUtil.now());
            }

            //先验证邮箱是否已经被注册
            Manager byName = this.findByName(manager.getUsername());
            if (byName != null){
                throw new BusinessException("已经注册，不能再次注册。");
            }

            if(manager.getCode()!=null){
                //String codes = (String) request.getSession().getAttribute("code");
                if( !checkCode.equals(manager.getCode())){
                    throw new BusinessException("验证码输入错误。");
                }
            }


            manager.setPassword(SecureUtil.md5(manager.getPassword()));
            managerMapper.insert(manager);
            return manager;
        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorMessage());
        }
    }

    @Override
    public String sendOutEmail(String username) throws BusinessException{
        try {
            //先验证邮箱是否已经被注册
            Manager byName = this.findByName(username);
            if (byName != null){
                throw new BusinessException("邮箱已经注册，不能再次注册。");
            }

            Properties props = new Properties();
            // 表示SMTP发送邮件，必须进行身份验证
            props.put("mail.smtp.auth", "true");
            //此处填写SMTP服务器
            props.put("mail.smtp.host", mailProperties.getHost());
            //端口号，QQ邮箱端口587
            props.put("mail.smtp.port", mailProperties.getPort());
            // 此处填写，写信人的账号
            props.put("mail.user", mailProperties.getUsername());
            // 此处填写16位STMP口令
            props.put("mail.password", mailProperties.getPassword());

            // 构建授权信息，用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {

                protected PasswordAuthentication getPasswordAuthentication() {
                    // 用户名、密码，都不用改直接copy
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息，创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人，
            InternetAddress form = new InternetAddress(props.getProperty("mail.user"));
            message.setFrom(form);
            // 设置收件人的邮箱
            InternetAddress to = new InternetAddress(username);
            message.setRecipient(Message.RecipientType.TO, to);
            // 设置邮件标题
            message.setSubject("标题：请收好你在Just的博客的注册码");
            // 设置邮件的内容体
            String checkCode = String.valueOf(new Random().nextInt(899999) + 100000);
            String str ="<h4>欢迎您在Just的博客注册</h4>"+"<p style='color:#F00'>您的验证码为:"+checkCode+"</p>";
            message.setText(str,"utf-8");
            // 最后当然就是发送邮件啦
            Transport.send(message);
            return checkCode;
        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorMessage());
        } catch (AddressException e) {
            throw new RuntimeException(e);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<Manager> getManagerByPage(Manager manager,Manager currentManager) {
        if (currentManager.getType().equals(ConstUtil.SUPER_ADMIN)){
            manager.setType(ConstUtil.ADMIN);
        }
        if (currentManager.getType().equals(ConstUtil.ADMIN)){
            manager.setType(ConstUtil.BOLG_MIN);
        }

        QueryWrapper<Manager> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(StringUtils.isNotBlank(manager.getUsername()),Manager::getUsername,manager.getUsername())
                             .like(StringUtils.isNotBlank(manager.getName()),Manager::getName,manager.getName())
                             .eq(StringUtils.isNotBlank(manager.getType()),Manager::getType,manager.getType())
                             .orderByDesc(Manager::getCreateTime)
                             .orderByDesc(Manager::getStatus);
        return managerMapper.selectList(queryWrapper);
    }

    @Override
    public void delManager(List<Integer> ids) throws BusinessException{
        try {
            managerMapper.deleteBatchIds(ids);
        }catch (BusinessException e){
            throw new BusinessException(e.getErrorMessage());
        }
    }

    @Override
    public void stopManager(List<Integer> ids, int key)throws BusinessException{
        try {
            List<Manager> managers = managerMapper.selectBatchIds(ids);
            if(managers.stream().anyMatch(x->x.getStatus()==key)){
                throw new BusinessException("已经是"+ DataStatusEnum.getValue(key)+"状态");
            }
            managers.forEach(x->x.setStatus(key));
            this.updateBatchById(managers);
        }catch (BusinessException e){
            throw new BusinessException(e.getErrorMessage());
        }
    }

    @Override
    public Manager updateManager(Manager manager) {
        QueryWrapper<Manager> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().ne(Manager::getId,manager.getId())
                             .eq(Manager::getUsername,manager.getUsername())
                             .eq(Manager::getStatus, ConstUtil.DEFAULT_STATE);

        if (managerMapper.selectCount(queryWrapper)>0){
             throw new BusinessException("用户名或者昵称已经存在");
        }

        if (manager.getPassword()!=null){
            manager.setPassword(SecureUtil.md5(manager.getPassword()));
        }

        managerMapper.updateById(manager);
        return manager;
    }

}
